home *** CD-ROM | disk | FTP | other *** search
- //XMM.CPP
-
- #include <iostream.h>
- #include <fstream.h>
- #include <dos.h>
- #include <dir.h>
- #include <stdlib.h>
- #include <string.h>
- #include "xmm.h"
-
- void DashXMM::detect(void){
- REGS inregs;
- REGS outregs;
- inregs.x.ax = 0x4300;
- int86(XMSINT, &inregs, &outregs);
- int comparing = outregs.h.al;
- detected = FALSE;
- if (comparing == 0x80) detected = TRUE;
- }
-
-
- XMSerror DashXMM::initialize(void){
- initialized = FALSE;
- if (detected){
- REGS inregs;
- REGS outregs;
- SREGS segregs;
- inregs.x.ax = 0x4310;
- int86x(XMSINT, &inregs, &outregs, &segregs);
- dword bx, es;
- bx = outregs.x.bx;
- es = segregs.es;
- CONTROL = (void far(*)())(MK_FP(es, bx));
- initialized = TRUE;
- get_versions();
- return OK;
- }
- if (!detected){
- if (request_swapfile){
- initialized = TRUE;
- using_swapfile = TRUE;
- return OK;
- }
- }
- initialized = FALSE;
- return XMS_NOT_INITIALIZED;
- }
-
- void DashXMM::get_versions(void){
- if (detected){
- if (initialized){
- XMS_version = 0;
- driver_version = 0;
- if(!using_swapfile){
- _AH = XMS_const::GET_VERSION_NUMBER;
- CONTROL();
- XMS_version = _AX;
- driver_version = _BX;
- }
- }
- }
- }
-
- XMSerror DashXMM::query_free_XMS(XMSfree& freemem){
- if (detected){
- if (initialized){
- if (!using_swapfile){
- _AH = XMS_const::QUERY_FREE_XMS;
- CONTROL();
- if (_AX == FAILURE){
- if (verbose) display_error(XMSerror(_BL));
- return XMSerror(_BL);
- }
- freemem.largest = dword(_AX * 1024L);
- _AH = XMS_const::QUERY_FREE_XMS;
- CONTROL();
- if (_AX == FAILURE){
- if (verbose) display_error(XMSerror(_BL));
- return XMSerror(_BL);
- }
- freemem.total = dword(_DX * 1024L);
- return OK;
- }
- }
- }
- return XMS_NOT_INITIALIZED;
- }
-
- XMSerror DashXMM::allocate(dword bytes){
- if ((detected) || (using_swapfile == TRUE)){
- if (initialized){
- boolean need_swapfile = using_swapfile;
- const long KB = 1024;
- int KB_requested = 0;
- int byte_overflow = 0;
- dword bytes_granted = 0;
- byte_overflow = bytes % KB;
- KB_requested = int(bytes / KB);
- if (byte_overflow > 0) KB_requested++;
- bytes_granted = long(KB_requested) * KB;
- if (!using_swapfile){
- XMS_handle = 0;
- _DX = KB_requested;
- _AH = XMS_const::ALLOCATE_XMS;
- CONTROL();
- if (_AX) XMS_handle = _DX;
- if (int(_AX) == FAILURE){
- if (verbose) display_error(XMSerror(_BL));
- if (request_swapfile) need_swapfile = TRUE;
- if (!request_swapfile) return(XMSerror(_BL));
- }
- if (!need_swapfile){
- bytes_allocated = bytes_granted;
- using_swapfile = FALSE;
- if (verbose){
- cout << "\nRequested XMS Block of " << bytes << " bytes.\n";
- cout << "\nGranted block, in XMS, of " << bytes_allocated << " bytes.\n";
- cout << "\nSwapfile was not necessary.\n";
- }
- return OK;
- }
- }
- if (need_swapfile){
- XMSerror error = create_SF(KB_requested);
- if (error == FAILURE){
- if (verbose) display_error(XMSerror(_BL));
- return XMSerror(error);
- }
- if (verbose){
- cout << "Requested XMS Block of " << bytes << " bytes.\n";
- cout << "Granted block of SWAPFILE of " << bytes_allocated << " bytes.\n";
- cout << "Swapfile needed to be created to allocate this memory.\n";
- }
- return OK;
- }
- }
- }
- if (verbose){
- cout << "\nError: XMS was either not detected or not initialized.\n";
- }
- return XMS_NOT_INITIALIZED;
- }
-
- XMSerror DashXMM::free(void){
- if (bytes_allocated == 0){
- XMSerror error = FAILURE;
- if (verbose) display_error(error);
- return error;
- }
- if ((detected) || (using_swapfile == TRUE)){
- if (initialized){
- if (!using_swapfile){
- _DX = XMS_handle;
- _AH = XMS_const::FREE_XMS;
- CONTROL();
- if (int(_AX) == FAILURE){
- if (verbose) display_error(XMSerror(_BL));
- return XMSerror(_BL);
- }
- return OK;
- }
- if (using_swapfile){
- delete_SF();
- return OK;
- }
- }
- }
- if (verbose){
- cout << "\nError: XMS was either not detected or not initialized.\n";
- }
- return XMS_NOT_INITIALIZED;
- }
-
- //the move function is overloaded...handles 3 kinds of move:
- //1) XMS->XMS
- //2) CONVENTIONAL->XMS
- //3) XMS->CONVENTIONAL
-
- //they're fast...very fast
-
- XMSerror DashXMM::move(dword bytes, void far* address_to, dword offset_from){
- //creates move struct conventional->XMS
- if ((int(bytes % 2)) > 0) bytes++; //length must be even
- EMMstruct.length = bytes;
- EMMstruct.src_handl = XMS_handle;
- EMMstruct.src_offset = dword(offset_from);
- EMMstruct.dest_handl = 0;
- EMMstruct.dest_offset = dword(address_to);
- word movestruct = FP_OFF(&EMMstruct);
-
- if ((detected) || (using_swapfile == TRUE)){
- if (detected){
- if (initialized){
- _SI = movestruct;
- _AH = XMS_const::MOVE_XMS;
- CONTROL();
- if (_AX == FAILURE){
- if (verbose) display_error(XMSerror(_BL));
- return XMSerror(_BL);
- }
- return OK;
- }
- }
- if (using_swapfile){
- SF_move(bytes, address_to, offset_from);
- return OK;
- }
- }
- if (verbose){
- cout << "\nError: XMS was either not detected or not initialized.\n";
- }
- return XMS_NOT_INITIALIZED;
- }
-
- XMSerror DashXMM::move(dword bytes, dword offset_to, dword offset_from){
- //creates move struct conventional->XMS
- if ((int(bytes % 2)) > 0) bytes++; //length must be even
- EMMstruct.length = bytes;
- EMMstruct.src_handl = XMS_handle;
- EMMstruct.src_offset = dword(offset_from);
- EMMstruct.dest_handl = XMS_handle;
- EMMstruct.dest_offset = dword(offset_to);
- word movestruct = FP_OFF(&EMMstruct);
-
- if ((detected) || (using_swapfile == TRUE)){
- if (detected){
- if (initialized){
- _SI = movestruct;
- _AH = XMS_const::MOVE_XMS;
- CONTROL();
- if (_AX == FAILURE){
- if (verbose) display_error(XMSerror(_BL));
- return XMSerror(_BL);
- }
- return OK;
- }
- }
- if (using_swapfile){
- SF_move(bytes, offset_to, offset_from);
- return OK;
- }
- }
- if (verbose){
- cout << "\nError: XMS was either not detected or not initialized.\n";
- }
- return XMS_NOT_INITIALIZED;
- }
-
-
-
- XMSerror DashXMM::move(dword bytes, dword offset_to, void far* address_from){
- //creates move struct conventional->XMS
- if ((int(bytes % 2)) > 0) bytes++; //length must be even
- EMMstruct.length = bytes;
- EMMstruct.src_handl = 0;
- EMMstruct.src_offset = dword(address_from);
- EMMstruct.dest_handl = XMS_handle;
- EMMstruct.dest_offset = dword(offset_to);
- word movestruct = FP_OFF(&EMMstruct);
-
- if ((detected) || (using_swapfile == TRUE)){
- if (detected){
- if (initialized){
- _SI = movestruct;
- _AH = XMS_const::MOVE_XMS;
- CONTROL();
- if (_AX == FAILURE){
- if (verbose) display_error(XMSerror(_BL));
- return XMSerror(_BL);
- }
- return OK;
- }
- }
- if (using_swapfile){
- SF_move(bytes, offset_to, address_from);
- return OK;
- }
- }
- if (verbose){
- cout << "\nError: XMS was either not detected or not initialized.\n";
- }
- return XMS_NOT_INITIALIZED;
- }
-
- #pragma warn -par
-
- XMSerror DashXMM::lock(void far* ptr){
- if (detected){
- if (initialized){
- _DX = XMS_handle;
- _AH = XMS_const::LOCK_XMS;
- CONTROL();
- ptr = MK_FP(_DX, _BX);
- if (_AX == FAILURE){
- if (verbose) display_error(XMSerror(_BL));
- return XMSerror(_BL);
- }
- return OK;
- }
- }
- if (verbose){
- cout << "\nError: XMS was either not detected or not initialized.\n";
- }
- return XMS_NOT_INITIALIZED;
- }
-
- #pragma warn +par
-
- XMSerror DashXMM::unlock(void){
- if (detected){
- if (initialized){
- _DX = XMS_handle;
- _AH = XMS_const::UNLOCK_XMS;
- CONTROL();
- if (_AX == FAILURE){
- if (verbose) display_error(XMSerror(_BL));
- return XMSerror(_BL);
- }
- return OK;
- }
- }
- if (verbose){
- cout << "\nError: XMS was either not detected or not initialized.\n";
- }
- return XMS_NOT_INITIALIZED;
- }
-
-
-
- void DashXMM::display_error(XMSerror error){
- char s[80];
- if (verbose){
- cout << "DashXMM: Error reported by XMS driver:\n";
- cout << "Error #: " << int(error) << "\n";
- switch(error){
- case FAILURE: cout << "Failed operation.";
- break;
- case OK: cout << "Reports OK";
- break;
- case XMS_NOT_INITIALIZED: cout << "XMS is not initialized.";
- break;
- case NOT_ENOUGH_XMS: cout << "Not enough XMS.";
- break;
- case FUNCTION_NOT_IMPLEMENTED: cout << "Function not implemented.";
- break;
- case VDISK_DETECTED: cout << "VDisk was detected.";
- break;
- case A20_ERROR: cout << "A20 line error";
- break;
- case GENERAL_ERROR: cout << "General Driver error";
- break;
- case UNRECOVERABLE_ERROR: cout << "Unrecoverable driver error.";
- break;
- case HMA_DOES_NOT_EXIST: cout << "HMA doesn't exist.";
- break;
- case HMA_IN_USE: cout << "HMA is already in use.";
- break;
- case DX_LESS_THAN_HMAMIN: cout << "DX < /HMAMIN parameter";
- break;
- case HMA_NOT_ALLOCATED: cout << "HMA not allocated.";
- break;
- case A20_STILL_ENABLED: cout << "A20 line still enabled.";
- break;
- case NO_MORE_MEMORY: cout << "No more XMS available.";
- break;
- case NO_MORE_HANDLES: cout << "All handles have been used up.";
- break;
- case INVALID_HANDLE: cout << "Invalid handle specified.";
- break;
- case SOURCE_HANDLE_INVALID: cout << "Source handle is invalid.";
- break;
- case SOURCE_OFFSET_INVALID: cout << "Source offset is invalid.";
- break;
- case DEST_HANDLE_INVALID: cout << "Destination handle is invalid.";
- break;
- case DEST_OFFSET_INVALID: cout << "Destination offset is invalid.";
- break;
- case LENGTH_INVALID: cout << "Length specified is invalid.";
- break;
- case INVALID_OVERLAP: cout << "Invalid overlap requested.";
- break;
- case PARITY_ERROR: cout << "Parity error.";
- break;
- case BLOCK_NOT_LOCKED: cout << "Block is not locked.";
- break;
- case BLOCK_LOCKED: cout << "Block is locked.";
- break;
- case BLOCK_LOCK_COUNT_OVERFLOW: cout << "Block lock count overflow.";
- break;
- case LOCK_FAILED: cout << "Locking failed.";
- break;
- case SMALLER_UMB_AVAIL: cout << "Only a smaller UMB is available.";
- break;
- case NO_UMB_AVAIL: cout << "No UMB is available.";
- break;
- case UMB_SEGMENT_NUMBER_INVALID: cout << "UMB segment num. invalid.";
- break;
- default: cout << "Undefined Error";
- }
- cout << "\n";
- }
- }
-
-
- XMSerror DashXMM::query_free_SF(XMSfree& freemem){
- struct dfree free;
- long avail;
- int drive = SF_drive;
-
- drive = getdisk();
- getdfree(drive+1, &free);
- if (free.df_sclus == 0xFFFF)
- {
- if (verbose) cout<<("Error in getdfree() call\n");
- return FAILURE;
- }
-
- avail = (long) free.df_avail
- * (long) free.df_bsec
- * (long) free.df_sclus;
- freemem.total = avail;
- freemem.largest = avail;
- return OK;
- }
-
- XMSerror DashXMM::create_SF(dword Kbytes){
- //first, check to make sure there's enough space
- XMSfree freedisk;
- XMSerror error = query_free_SF(freedisk);
- if (error == FAILURE){
- if (verbose) display_error(XMSerror(error));
- return XMSerror(error);
- }
- if (freedisk.largest < dword(Kbytes * 1024)){
- error = NOT_ENOUGH_XMS;
- if (verbose) display_error(XMSerror(error));
- return XMSerror(error);
- }
-
- //now that we are relatively sure that we'll be able to handle this,
- //let's open the file.
- swapfile.open(swapfile_name, ios::out);
- if (!swapfile.good()){
- if(verbose) cout << "\nError opening file " << swapfile_name << "\n\n";
- return FAILURE;
- }
- //writes blank pages so that we can seekp() whereever we want.
- for (int i = 0; i < (Kbytes); i++){
- for (int j = 0; j < 1024UL; j++) swapfile.put(0);
- }
- //we now have a blank file, it needs to be closed and opened for ios::ate
- //to be read, however.
- swapfile.close();
- swapfile.open(swapfile_name, ios::in | ios::out | ios::ate);
- //now that that's handled, the other routines do the rest!
- bytes_allocated = dword(Kbytes * 1024UL);
- using_swapfile = TRUE;
- return OK;
- }
-
- void DashXMM::delete_SF(void){
- swapfile.close();
- unlink(swapfile_name);
- }
-
- XMSerror DashXMM::SF_move(dword bytes, dword offset_to, void far* address_from){
- char far* byte_from_pointer = (char far*)(address_from);
- dword i;
- for (i = 0; i < bytes; i++){
- swapfile.seekp(offset_to+i);
- swapfile.put(byte_from_pointer[i]);
- }
- if (verbose) cout << "Swapfile move completed.\n";
- return OK;
- }
-
- XMSerror DashXMM::SF_move(dword bytes, void far* address_to, dword offset_from){
- char far* byte_to_pointer = (char far*)(address_to);
- dword i;
- for (i = 0; i < bytes; i++){
- swapfile.seekg(offset_from+i);
- byte_to_pointer[i] = swapfile.get();
- }
- if (verbose) cout << "Swapfile move completed.\n";
- return OK;
- }
-
- XMSerror DashXMM::SF_move(dword bytes, dword offset_to, dword offset_from){
- if (offset_to > offset_from){
- if((offset_from + bytes) > offset_to){
- if (verbose) display_error(INVALID_OVERLAP);
- return INVALID_OVERLAP;
- }
- }
- if (offset_from > offset_to){
- if ((offset_to + bytes) > offset_from){
- if (verbose) display_error(INVALID_OVERLAP);
- return INVALID_OVERLAP;
- }
- }
- dword i;
- char putting;
- for (i = 0; i < bytes; i++){
- swapfile.seekg(offset_from+i);
- putting = swapfile.get();
- swapfile.seekp(offset_to+i);
- swapfile.put(putting);
- }
- if (verbose) cout << "Swapfile move completed.\n";
- return OK;
- }
-
- XMSerror DashXMM::query(XMSfree& freeXMS){
- XMSerror error;
- if (verbose) cout << "Querying:\n";
- error = query_free_XMS(freeXMS);
- if (error != OK){
- if (verbose) display_error(error);
- if (verbose) cout << "Error, querying Swapfile instead.\n";
- error = query_free_SF(freeXMS);
- }
- if (verbose) cout << "\nLargest: " << freeXMS.largest << ", total: " << freeXMS.total << "\n";
- return error;
- }
-
- DashXMM::DashXMM(boolean verbosity){ //constructor for NO SWAPFILE REQUESTED!
- using_swapfile = FALSE;
- verbose = verbosity;
- request_swapfile = FALSE;
- if (verbose) cout << "Detecting XMS.\n";
- detect();
- if (verbose) cout << "Initializing XMS.\n";
- initialize();
- }
-
- DashXMM::DashXMM(boolean verbosity, char* s){ //const. for SWAPFILE REQUEST
- using_swapfile = FALSE;
- verbose = verbosity;
- request_swapfile = TRUE;
- strcpy(swapfile_name, s);
- if (verbose) cout << "Detecting XMS.\n";
- detect();
- if (verbose) cout << "Initializing XMS.\n";
- initialize();
- }
-
- DashXMM::~DashXMM(void){
- }
-